/**
 * @author liangxi
 * @since 2024/7/23
 */

#ifndef DESIGNPATTERN_SINGLETON5_H
#define DESIGNPATTERN_SINGLETON5_H


#include <atomic>

class Singleton5 {

public:
    /**
     * C++11之后实现的安全的双检查加锁方法
     * load():用于从原子变量中读取数据，并保证读取操作是原子性的，不回被其它线程打断
     * store():用于将一个值原子性地存储到原子变量中，保证在写入地过程中，不会有其它线程读取到不完整的值
     *
     */
    static Singleton5 *getInstance() {
        Singleton5 *tmp = mInstance.load(std::memory_order_relaxed);
        std::atomic_thread_fence(std::memory_order_acquire);
        if (nullptr == tmp) {
            std::lock_guard<std::mutex> lock(mutex);
            tmp = mInstance.load(std::memory_order_relaxed);
            if (nullptr == tmp) {
                tmp = new Singleton5;
                std::atomic_thread_fence(std::memory_order_release);
                mInstance.store(tmp, std::memory_order_relaxed);
            }
        }
        return tmp;
    }

private:
    Singleton5() = default;

    Singleton5(const Singleton5 &rhs) = default;

    static std::atomic<Singleton5 *> mInstance;
    static std::mutex mutex;
};

std::atomic<Singleton5 *> Singleton5::mInstance = nullptr;
std::mutex Singleton5::mutex;


#endif //DESIGNPATTERN_SINGLETON5_H
